package com.avego.game;

import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;

public class Player implements Callable<Boolean>
{
	private int playerNumber;
	private Board board;
	private Referee referee;
	private boolean isSuspended = false;
	private boolean winner = false;
	private Random random = new Random();
	private long nextMoveTimeout;
	private long suspendedNextMoveTimeout;

	public Player()
	{

	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.Callable#call()
	 */
	public Boolean call()
	{
		try
		{
			while (true)
			{
				if (winner)
				{
					return true;
				}
				if (isSuspended)
				{
					Thread.sleep(suspendedNextMoveTimeout);

					boolean canPlay = referee.canPlayerReturnToGame(this);

					if (!canPlay)
					{
						return false;
					}

					isSuspended = false;
				}

				synchronized (board)
				{
					List<BoardCoordinates> availableMoves = board
							.getAvailableMoves(this);

					BoardCoordinates moveTo = availableMoves.get(random
							.nextInt(availableMoves.size()));

					board.movePlayer(this, moveTo);
				}

				Thread.sleep(nextMoveTimeout);

			}
		}
		catch (InterruptedException e)
		{
			e.printStackTrace();
			return false;
		}
	}

	
	/**
	 * Sets the player as suspended.
	 */
	public void setPlayerAsSuspended()
	{
		isSuspended = true;
	}

	/**
	 * Mark the player as a winner
	 */
	public void win()
	{
		winner = true;
	}

	public int getPlayerNumber()
	{
		return playerNumber;
	}

	public void setPlayerNumber(int num)
	{
		this.playerNumber = num;
	}


	public Board getBoard()
	{
		return board;
	}

	public void setBoard(Board board)
	{
		this.board = board;
	}

	public Referee getReferee()
	{
		return referee;
	}

	public void setReferee(Referee referee)
	{
		this.referee = referee;
	}

	public long getNextMoveTimeout()
	{
		return nextMoveTimeout;
	}

	public void setNextMoveTimeout(long nextMoveTimeout)
	{
		this.nextMoveTimeout = nextMoveTimeout;
	}

	public long getSuspendedNextMoveTimeout()
	{
		return suspendedNextMoveTimeout;
	}

	public void setSuspendedNextMoveTimeout(long suspendedNextMoveTimeout)
	{
		this.suspendedNextMoveTimeout = suspendedNextMoveTimeout;
	}

	public boolean isSuspended()
	{
		return isSuspended;
	}

}
